<template>
  <div
    id="picture-viewer"
    :style="maskContainer"
    @click.self="closeViewer"
  >
    <!-- 头部 -->
    <div class="to-exit" @click="closeViewer">
      <img :src="backIcon" class="back" alt="" >
    </div>
    <!-- 操作按钮 -->
    <div v-if="bigShowType.isImage" class="handleContainer">
      <i class="el-icon-zoom-out tool-icon" @click="reduce"/>
      <i class="el-icon-zoom-in tool-icon" @click="enlarge"/>
      <i class="el-icon-full-screen tool-icon" @click="resize"/>
      <i class="el-icon-refresh-right tool-icon" @click="rotate"/>
    </div>

    <!-- 图片容器 -->
    <div v-loading="loading" v-if="loading" style="width: 100%;height: calc(100% - 80px);" />
    <img
      v-if="bigShowType.isImage"
      v-show="!loading"
      ref="bigImg"
      :src="bigImageUrl"
      :style="bigImgStyle"
      alt=""
      @mousewheel.prevent="imgScroll"
    >
    <VideoPlayer
      v-else
      ref="veo"
      :src="bigImageUrl"
      :autoplay="true"
      :play-width="60"
      :style="{ width: showMobilePage && '100% !important' }"
      class="video-player"
      width="100%"
      height="100%"
    />
    <div v-if="imgLength > 1" :style="{ height: !isShowSliderNav && '80px' }" class="fixedHandle">
      <swiper v-if="isShowSliderNav" :options="swiperOption" class="swiper">
        <swiper-slide
          v-for="(slide, index) in imgData"
          :key="slide.uid"
          :class="index === imgIndex ? 'active-item' : ''"
        >
          <div ref="thumbnailItem" @click="switchImgUrl(index, $event)">
            <img :src="slide.url" alt="" style="object-fit: cover;">
          </div>
        </swiper-slide>
        <template v-if="isShowSliderNav">
          <div slot="button-prev" class="swiper-button-prev"/>
          <div slot="button-next" class="swiper-button-next"/>
        </template>
      </swiper>
      <div v-else class="thumbnailContainer">
        <ul>
          <li
            v-for="(item, index) in imgData"
            ref="thumbnailItem"
            :key="index"
            :class="index === imgIndex ? 'active-item' : ''"
            @click="switchImgUrl(index, $event)"
          >
            <img v-if="isImg(item.name)" :src="item.url" alt="" style="object-fit: cover;">
            <VideoPlayer
              v-else
              :src="item.url"
              :autoplay="false"
              :play-width="48"
              class="video-preview"
            />
          </li>
        </ul>
      </div>
    </div>
    <!-- 左边箭头 -->
    <div
      v-if="imgIndex > 0"
      :style="{ zIndex: isOpen ? -1 : '' }"
      class="arrowCon leftArrowCon"
      @click="handlePrev"
    >
      <div class="arrowBox">
        <img
          :src="preIcon"
          class="leftArrow"
        >
      </div>
    </div>
    <!-- 右边箭头 -->
    <div>
      <div
        v-if="imgIndex < imgLength - 1"
        :style="{ zIndex: isOpen ? -1 : '' }"
        class="arrowCon rightArrowCon"
        @click="handleNext"
      >
        <div class="arrowBox">
          <img
            :src="nextIcon"
            class="rightArrow"
          >
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { Swiper, SwiperSlide } from 'vue-awesome-swiper';
import { mapState } from 'vuex';
import math from '@/utils/math';
import 'swiper/css/swiper.css';
import VideoPlayer from '@/components/Common/upAttachment/VideoPlayer';
import preIcon from '@/assets/image/pre.png';
import nextIcon from '@/assets/image/next.png';
import leftIcon from '@/assets/image/left.png';
import rightIcon from '@/assets/image/right.png';
import backIcon from '@/assets/image/back.png';
export default {
  components: {
    Swiper,
    SwiperSlide,
    VideoPlayer
  },
  data() {
    return {
      preIcon, nextIcon, leftIcon, rightIcon, backIcon,
      isOpen: false,
      moveId: 0,
      // 默认不显示左右切换箭头
      leftArrowShow: false,
      rightArrowShow: false,
      // 图片容器数据
      rotateDeg: 0,
      bigImageUrl: '',
      bigShowType: { isImage: true, icon: '' }, // 不是图片的时候 展示 icon
      bigImgName: '',
      imgLength: 0,
      imgIndex: 0,
      imgSize: '',
      bigImgConTrnWidth: '',
      bigImgConTrnHeight: '',
      isShowSliderNav: false,
      loading: false,
      imgContainer: {
        width: '160px',
        height: '100%'
      },
      bigImgStyle: {
        display: 'block',
        width: '',
        height: '',
        userSelect: 'none',
        transform: 'unset'
      },
      url: '',
      swiperOption: {
        slidesPerView: 3,
        slideToClickedSlide: true,
        spaceBetween: 13,
        watchOverflow: true,
        simulateTouch: false,
        loop: false,
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev'
        }
      },
      gap: 80,
      isFillHeight: false
    };
  },
  computed: {
    ...mapState({
      'showImageViewer': state => state.app.imgPreviewObj.showImageViewer,
      'imgData': state => state.app.imgPreviewObj.imgData,
      'selectIndex': state => state.app.imgPreviewObj.selectIndex,
      'appendToBody': state => state.app.imgPreviewObj.appendToBody,
      'showMobilePage': state => state.app.showMobilePage
    }),
    maskContainer() {
      return {
        width: '100%',
        height: '100%',
        background: 'rgba(0,0,0,0.85)',
        position: 'fixed',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        zIndex: 9999,
        alignItems: this.isFillHeight ? 'flex-start' : 'center'
      };
    },
    additionHeight() {
      return this.imgLength > 1 ? 85 : 0;
    }
  },
  watch: {
    $route: {
      handler() {
        this.closeViewer();
      },
      deep: true
    },
    'showImageViewer': {
      handler() {
        this.initBigImg();
      },
      immediate: true,
      deep: true
    }
  },
  mounted() {
    this.initBigImg();
    if (!this.appendToBody) {
      document
        .getElementById('picture-viewer')
        .addEventListener('click', (e) => {
          e.stopPropagation();
        });
    }

    if (this.appendToBody) {
      document.body.appendChild(this.$el);
    }
    this.imgLength = this.imgData.length;
    var self = this;
    this.$refs.bigImg.onload = () => {
      self.loading = false;
      if (this.bigShowType.isImage) {
        self.init();
      }
    };
    window.addEventListener('resize', this.handleIsShowSliderNav);
  },
  beforeDestroy() {
    if (document.getElementById('picture-viewer')) {
      document
        .getElementById('picture-viewer')
        .removeEventListener('click', (e) => {
          e.stopPropagation();
        });
    }

    if (this.appendToBody && this.$el && this.$el.parentNode) {
      this.$el.parentNode.removeChild(this.$el);
    }
    window.removeEventListener('resize', this.handleIsShowSliderNav);
  },
  methods: {
    initBigImg() {
      this.imgIndex = this.selectIndex;
      this.$nextTick(() => {
        this.bigImgName = this.imgData[this.imgIndex].name;
        this.bigImageUrl = this.imgData[this.imgIndex].url + `?attname=${encodeURIComponent(this.bigImgName)}`;
        this.getShowTypeInfo(this.bigImgName);
        this.handleIsShowSliderNav();
        if (this.bigShowType.isImage) {
          this.loading = true;
        }
      });
    },
    handleIsShowSliderNav() {
      if (this.imgLength > 1 && this.$refs.thumbnailItem) {
        // 大于1的时候才会展示缩略图
        // 计算缩略图展示个数
        const container = document.querySelector('.fixedHandle');
        if (container) {
          const containerWidth = container.offsetWidth;
          this.swiperOption.slidesPerView = Math.floor((containerWidth - 24) / 80);
          this.isShowSliderNav = this.imgLength > this.swiperOption.slidesPerView;
        }
      }
    },
    imgScroll(e) {
      const _this = this;
      const ev = e || window.event;
      const screenH =
        document.documentElement.scrollHeight || document.body.scrollHeight;
      if (this.$refs.bigImg.height > screenH) {
        if (ev.wheelDelta) {
          if (ev.wheelDelta > 0) {
          // 当滑轮向上滚动时
            _this.imgScrollTop();
          }
          if (ev.wheelDelta < 0) {
            _this.imgScrollBottom();
          }
        } else if (ev.detail) {
          if (ev.detail > 0) {
          // 当滑轮向上滚动时
            _this.imgScrollTop();
          }
          if (ev.detail < 0) {
            _this.imgScrollBottom();
          }
        }
      }
    },
    imgScrollTop() {
      this.moveId = this.moveId + 1;
      const x = this.moveId * 50;
      this.bigImgStyle.transform = `translateY(${x}px)`;
    },
    imgScrollBottom() {
      this.moveId = this.moveId - 1;
      const x = this.moveId * 50;
      this.bigImgStyle.transform = `translateY(${x}px)`;
    },
    mousewheel(e) {
      if (this.bigShowType.isImage) {
        const _this = this;
        const ev = e || window.event;
        ev.preventDefault();
        //  ;
        if (ev.wheelDelta) {
          if (ev.wheelDelta > 0) {
          // 当滑轮向上滚动时
            _this.enlarge();
          }
          if (ev.wheelDelta < 0) {
            _this.reduce();
          }
        } else if (ev.detail) {
          if (ev.detail > 0) {
          // 当滑轮向上滚动时
            _this.enlarge();
          }
          if (ev.detail < 0) {
            _this.reduce();
          }
        }
      }
    },
    init() {
      const screenW =
        document.documentElement.offsetWidth || document.body.offsetWidth;
      const screenH =
        document.documentElement.scrollHeight || document.body.scrollHeight;
      this.$nextTick(() => {
        let radio = 1;
        const { naturalHeight, naturalWidth } = this.$refs.bigImg;
        const isWidthOver = naturalWidth > screenW;
        const isHeightOver = naturalHeight > screenH - this.additionHeight;
        this.isFillHeight = false;
        if (naturalWidth > screenW || naturalHeight > screenH - this.additionHeight) {
          const allOver = isWidthOver && isHeightOver;
          const maxLength = allOver ? (naturalWidth / screenW) > (naturalHeight / screenH) ? naturalWidth : naturalHeight : Math.max(naturalWidth, naturalHeight);
          radio = math.divide(maxLength, allOver ? (naturalWidth / screenW) > (naturalHeight / screenH) ? screenW : screenH - this.additionHeight : isWidthOver ? screenW : screenH - this.additionHeight);
          this.isFillHeight = naturalHeight > screenH && !allOver || allOver && (naturalWidth / screenW) < (naturalHeight / screenH);
        }
        this.bigImgConTrnWidth = math.divide(naturalWidth, radio);
        this.bigImgConTrnHeight = math.divide(naturalHeight, radio);
        this.imgContainer.width = this.bigImgConTrnWidth + 'px';
        this.bigImgStyle.width = this.bigImgConTrnWidth + 'px';
        this.bigImgStyle.height = this.bigImgConTrnHeight + 'px';
      });
    },
    arrayContain(array, string) {
      return array.some((item) => {
        return item === string;
      });
    },
    closeViewer() {
      this.$store.dispatch('ToggleImageViewer', { showImageViewer: false, imgData: [], selectIndex: 0 });
    },
    getShowTypeInfo(name) {
      const isImage = this.isImg(name);
      this.bigShowType = { isImage: isImage, icon: '' };
    },
    isImg(name) {
      const reg = /(\.(gif|png|jpg|jpeg|webp|bmp|tif))$/i;
      return reg.test(name);
    },
    isVideo(name) {
      const reg = /(\.(mp4|mkv|webm|avi|flv|mov|wmv))$/i;
      return reg.test(name);
    },
    // 点击缩略图切换图片
    switchImgUrl(num, e) {
      this.isOpen = false;
      const temp = this.imgIndex;
      this.imgIndex = num;
      this.bigImgName = this.imgData[num].name;
      this.bigImageUrl = this.imgData[num].url + `?attname=${encodeURIComponent(this.bigImgName)}`;
      this.getShowTypeInfo(this.bigImgName);
      if (this.bigShowType.isImage && temp !== num) {
        this.toggleImg();
      }
      this.bigImgStyle.transform = 'unset';
    },
    toggleImg() {
      this.loading = true;
      this.$nextTick(() => {
        const self = this;
        this.$refs.bigImg.onload = () => {
          self.loading = false;
          if (this.bigShowType.isImage) {
            self.init();
          }
        };
      });
    },
    // 放大
    enlarge: _.debounce(function() {
      this.$nextTick(function() {
        const screenW =
          document.documentElement.offsetWidth || document.body.offsetWidth;
        const screenH =
          document.documentElement.scrollHeight || document.body.scrollHeight;
        if (
          (this.$refs.bigImg.offsetWidth >= this.$refs.bigImg.offsetHeight &&
            this.$refs.bigImg.offsetHeight * 2 < screenH * 2) ||
          (this.$refs.bigImg.offsetHeight >= this.$refs.bigImg.offsetWidth &&
            this.$refs.bigImg.offsetWidth * 2 < screenW * 2)
        ) {
          this.bigImgStyle.transform = 'unset';
          this.bigImgStyle.width = this.$refs.bigImg.offsetWidth * 1.3 + 'px';
          this.bigImgStyle.height = this.$refs.bigImg.offsetHeight * 1.3 + 'px';
        }
      });
    }, 100),
    // 缩小
    reduce: _.debounce(function() {
      if (this.$refs.bigImg.offsetWidth > 80) {
        this.bigImgStyle.transform = 'unset';
        this.bigImgStyle.width = this.$refs.bigImg.offsetWidth * 0.7 + 'px';
        this.bigImgStyle.height = this.$refs.bigImg.offsetHeight * 0.7 + 'px';
      }
    }, 100),
    // 旋转
    rotate: _.debounce(function() {
      const numberAngle = [90, 180, 270, 360];
      const numberAngleSelect = numberAngle[this.rotateDeg] || 90;
      if (this.rotateDeg === numberAngle.length) {
        this.bigImgStyle.transform = `rotate(${numberAngleSelect}deg)`;
        this.rotateDeg = 1;
      } else {
        this.bigImgStyle.transform = `rotate(${numberAngleSelect}deg)`;
        this.rotateDeg++;
      }
    }, 100),
    // 缩放
    resize: _.debounce(function() {
      if (this.imgSize) {
        this.imgSize = '';
        this.bigImgStyle.transform = 'unset';
        this.init();
      } else {
        this.imgSize = 'fill';
        this.bigImgStyle.width = 'auto';
        this.bigImgStyle.height = 'auto';
      }
    }, 100),
    // 切换到上一张
    handlePrev() {
      this.isOpen = false;
      if (this.$refs.bigImg) {
        this.bigImgStyle.transform = 'rotate(0deg)';
        this.rotateDeg = 0;
      }

      this.imgIndex--;
      this.bigImgName = this.imgData[this.imgIndex].name;
      this.bigImageUrl = this.imgData[this.imgIndex].url + `?attname=${encodeURIComponent(this.bigImgName)}`;
      this.getShowTypeInfo(this.bigImgName);
      if (this.bigShowType.isImage) {
        this.toggleImg();
      }
    },
    // 切换到下一张
    handleNext() {
      this.isOpen = false;
      if (this.$refs.bigImg) {
        this.bigImgStyle.transform = 'rotate(0deg)';
        this.rotateDeg = 0;
      }

      this.imgIndex++;
      this.bigImgName = this.imgData[this.imgIndex].name;
      this.bigImageUrl = this.imgData[this.imgIndex].url + `?attname=${encodeURIComponent(this.bigImgName)}`;
      this.getShowTypeInfo(this.bigImgName);
      if (this.bigShowType.isImage) {
        this.toggleImg();
      }
    }
  }

};
</script>

<style lang="scss" scoped>
#picture-viewer {
  display: flex;
  justify-content: center;
  .image-container {
    height: 100%;
    overflow-y: auto;
    display: flex;
    justify-content: center;
    align-items: center;
    @include scrollBar($width: 0);
  }
  .video-player {
    width: 800px !important;
    height: 450px !important;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
  .video-preview {
    width: 56px !important;
    height: 56px !important;
    border-radius: 0;
    pointer-events: none;
    &::v-deep {
      .vjs-control-bar {
        display: none;
      }
    }
  }
  &::v-deep {
    .el-loading-mask {
      background-color: rgba(0, 0, 0, 0.7);
    }
    .tool-icon {
      width: 20px;
      height: 20px;
      font-size: 20px;
      color: #DDDDDD;
      cursor: pointer;
    }
    .swiper-container {
      height: 100%;
      .swiper-wrapper {
        align-items: center;
        .swiper-slide {
          width: 56px !important;
          height: 56px;
          margin-left: 16px;
          cursor: pointer;
          box-sizing: border-box;
          div {
            width: 100%;
            height: 100%;
            box-sizing: border-box;
          }
          img {
            width: 100%;
            height: 100%;
          }
          &:last-child {
            margin-right: 16px;
          }
        }
      }
      .swiper-button-prev {
        width: 16px;
        border-radius: 4px 0 0 4px;
        height: 56px;
        margin-top: -29px;
        background: rgba(255, 255, 255, 0.4);
        &::after {
          font-size: 14px;
          color: #fff;
          font-weight: bold;
        }
      }
      .swiper-button-next {
        width: 16px;
        border-radius: 0 4px 4px 0;
        height: 56px;
        margin-top: -29px;
        background: rgba(255, 255, 255, 0.4);
        &::after {
          font-size: 14px;
          color: #fff;
          font-weight: bold;
        }
      }
    }
  }
  .to-exit {
    position: absolute;
    left: 16px;
    top: 16px;
    border-radius: 50%;
    width: 48px;
    height: 48px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgba(0, 0, 0, 0.4);
    z-index: 9999;
    cursor: pointer;
    &:hover {
      background: rgba(0, 0, 0, 0.6);
    }
    img {
      width: 100%;
      height: 100%;
    }
  }
  .arrowCon {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    position: absolute;
    top: 50%;
    z-index: 99;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .leftArrowCon {
    left: -16px;
  }
  .rightArrowCon {
    right: -16px;
  }
  .arrowBox {
    width: 56px;
    height: 56px;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgba(0, 0, 0, 0.4);
    border-radius: 50%;
    &:hover {
      background: rgba(0, 0, 0, 0.8);
    }
  }
  .leftArrow, .rightArrow {
    width: 12px;
  }
  .fixedHandle {
    width: 100%;
    padding: 12px;
    position: fixed;
    left: 0;
    bottom: 0;
    overflow: hidden;
    z-index: 100;
    background: rgba(0, 0, 0, 0.8);
    .nav {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 16px;
      height: 80px;
      background: rgba(255, 255, 255, .2);
      position: absolute;
      top: 20px;
      img {
        width: 8px;
      }
      &:hover {
        background: rgba(255, 255, 255, .6);
      }
    }
    .to-left {
      left: 16px;
      border-radius: 4px 0 0 4px;
    }
    .to-right {
      right: 16px;
      border-radius: 0 4px 4px 0;
    }
  }
  .handleContainer {
    height: 40px;
    background: rgba(0, 0, 0, 0.4);
    line-height: 40px;
    border-radius: 20px;
    position: absolute;
    right: 16px;
    top: 16px;
    display: flex;
    align-items: center;
    padding: 0 24px;
    z-index: 9999;
    .tool-icon {
      margin-right: 24px;
      &:last-child {
        margin-right: 0;
      }
    }
  }
  .handleItem {
    width: 28px;
    height: 28px;
    color: white;
  }
  ul {
    padding: 0;
    margin: 0;
  }
  ul li {
    list-style: none;
    display: inline-block;
    width: 30px;
    height: 30px;
    margin-left: 20px;
    cursor: pointer;
  }

  .thumbnailContainer {
    flex: 1;
    max-width: 100%;
    height: 100%;
    position: absolute;
    left: 50%;
    bottom: 0;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    transform: translate(-50%, 0%);
    overflow-x: auto;
    overflow-y: hidden;
  }

  .thumbnailContainer ul {
    height: 100%;
    padding-top: 10px;
    padding-bottom: 10px;
    text-align: center;
    white-space: nowrap;
    display: flex;
    align-items: center;
  }
  .thumbnailContainer ul li {
    display: inline-block;
    width: 56px;
    height: 56px;
    box-sizing: border-box;
    margin-left: 16px;
    user-select: none;
    overflow: hidden;
  }
  .thumbnailContainer ul li:last-child {
    margin-right: 16px;
  }
  .thumbnailContainer ul li img {
    display: inline-block;
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .fade-enter-active,
  .fade-leave-active {
    transition: opacity 1s;
  }
  .fade-enter,
  .fade-leave-to {
    opacity: 0;
  }

  /* 添加border */
  .active-item {
    border: 4px solid #406eff;
    .video-preview {
      width: 48px !important;
      height: 48px !important;
    }
  }
  /* 修改原生的滚动条 */
  ::-webkit-scrollbar {
    /* 血槽宽度 */
    width: 8px;
    height: 8px;
  }
  ::-webkit-scrollbar-thumb {
    /* 拖动条 */
    background: rgba(0, 0, 0, 0.3);
    border-radius: 6px;
  }
  ::-webkit-scrollbar-track {
    /* 背景槽 */
    background: #ddd;
    border-radius: 6px;
  }
  /** 文件展示*/
  .file-show {
    position: absolute;
    top: 60%;
    left: 50%;
    width: 450px;
    height: 260px;
    margin-top: -150px;
    margin-left: -225px;
    background-color: white;
    border-radius: 10px;
    padding: 0 80px;
    .file-icon {
      // flex: 1;
      cursor: pointer;
      img {
        display: block;
        width: 60px;
        &:hover {
          transform: rotateY(180deg);
          // transform: scale(0.5);
          // transition: all 0.2s ease-in;
        }
      }
    }

    .file-handle {
      button {
        display: block;
        width: 120px;
        margin-left: 0;
        margin-right: 0;
        height: 34px;
      }
      button:first-child {
        margin-bottom: 20px;
      }
    }
  }
  .disabled {
    pointer-events: none;
    opacity: 0.1;
  }
}
</style>
